package com.juyu.miliao.api.dao.redis;

import com.alibaba.fastjson.JSONObject;
import com.juyu.miliao.api.dao.mysql.AreaDao;
import com.juyu.miliao.api.dao.mysql.UserInfoDao;
import com.juyu.miliao.api.dao.redis.usercache.UserInfoCache;
import com.juyu.miliao.api.domain.AreaInfo;
import com.juyu.miliao.api.domain.User;
import com.juyu.miliao.api.domain.dto.LocationDTO;
import com.juyu.miliao.api.util.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * @author xuanqicheng
 * @create 2019-07-15:09
 */
@Component
@Slf4j
public class MakeFriendsRedisDao {

    private static final String USER_LOCATION_HOST_ONLINE_KEY = "ZSET_MAKE_FRIENDS_USER_LOCATION_HOST_ONLINE:";

    private static final String USER_LOCATION_VIP_ONLINE_KEY = "ZSET_MAKE_FRIENDS_USER_LOCATION_VIP_ONLINE:";

    private static final String USER_LOCATION_OTHER_ONLINE_KEY = "ZSET_MAKE_FRIENDS_USER_LOCATION_OTHER_ONLINE:";

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private AreaDao areaDao;

    @Autowired
    private UserInfoCache userInfoCache;


    /**
     * 更新用户位置信息
     *
     * @param user
     * @param locationDTO
     * @param online
     */
    public void updateLocation(User user, LocationDTO locationDTO, int online) {

        if (locationDTO != null && StringUtils.isNotBlank(locationDTO.getProvince())
                && StringUtils.isNotBlank(locationDTO.getCity())) {

            if (StringUtils.isBlank(user.getLocationProvince())||
                    StringUtils.isBlank(user.getLocationCity())||
                    !user.getLocationProvince().equals(locationDTO.getProvince())||
                    !user.getLocationCity().equals(locationDTO.getCity())) {
                if(locationDTO.getProvince().equals("北京市")
                        ||locationDTO.getProvince().equals("天津市")
                ||locationDTO.getProvince().equals("上海市")||locationDTO.getProvince().equals("重庆市")){
                    user.setLocationCity(locationDTO.getProvince());
                }else {
                    user.setLocationCity(locationDTO.getCity());
                }
                user.setLocationProvince(locationDTO.getProvince());
                //经纬度 格式：纬度(lat),经度(lon)
                String location = "";
                if(StringUtils.isNotBlank(locationDTO.getLat())&&
                        StringUtils.isNotBlank(locationDTO.getLon())){
                    location = locationDTO.getLat()+","+locationDTO.getLon();
                }
                userInfoDao.updateUserLocation(user.getUserId(),user.getLocationCity(),user.getLocationProvince(),location);
                userInfoCache.deleteUserCacheInfo(user.getUserId());
            }
        }

        deleteMakeFriendsCache(user);
        if (online != 0) {
            addMakeFriendsCache(user,user.getLocationCity());
        }

    }

    /**
     * 添加缓存
     *
     * @param user
     * @param city
     */
    public void addMakeFriendsCache(User user, String city) {
        AreaInfo areaInfo = areaDao.selectAreaCityByName(city);

        int cityId = -1;
        if (areaInfo != null) {
            cityId = areaInfo.getAreaId();
        }


        if (user.getIsHost() == 1) {
            String key = USER_LOCATION_HOST_ONLINE_KEY + user.getSex();

            stringRedisTemplate.opsForZSet().add(key, user.getUserId() + "", cityId);

        } else {
            if (user.getIsVip() == 1 || user.getIsSvip()==1 || user.getIsPlatinumVip()==1) {
                String key = USER_LOCATION_VIP_ONLINE_KEY + user.getSex();
                stringRedisTemplate.opsForZSet().add(key, user.getUserId() + "", cityId);
            } else {
                String key = USER_LOCATION_OTHER_ONLINE_KEY + user.getSex();
                stringRedisTemplate.opsForZSet().add(key, user.getUserId() + "", cityId);
            }
        }

    }

    public void deleteMakeFriendsCache(User user) {
        stringRedisTemplate.opsForZSet().remove(USER_LOCATION_HOST_ONLINE_KEY + 1, user.getUserId() + "");
        stringRedisTemplate.opsForZSet().remove(USER_LOCATION_HOST_ONLINE_KEY + 2, user.getUserId() + "");
        stringRedisTemplate.opsForZSet().remove(USER_LOCATION_VIP_ONLINE_KEY + 1, user.getUserId() + "");
        stringRedisTemplate.opsForZSet().remove(USER_LOCATION_VIP_ONLINE_KEY + 2, user.getUserId() + "");
        stringRedisTemplate.opsForZSet().remove(USER_LOCATION_OTHER_ONLINE_KEY + 1, user.getUserId() + "");
        stringRedisTemplate.opsForZSet().remove(USER_LOCATION_OTHER_ONLINE_KEY + 2, user.getUserId() + "");
    }


    public List<String> getSameCityList(User user, Integer page, Integer pageSize) {
        int otherSex = 1;
        if (otherSex == user.getSex()) {
            otherSex = 2;
        }
        int startNum = PageUtil.getOffset(page, pageSize);

        String city = StringUtils.isNotBlank(user.getLocationCity()) ?
                user.getLocationCity():"";

        String province = StringUtils.isNotBlank(user.getLocationProvince()) ?
                user.getLocationProvince():"";


        AreaInfo areaInfo = areaDao.selectAreaCityByName(city);

        int cityId = -1;
        if (areaInfo != null) {
            cityId = areaInfo.getAreaId();
        }

        log.info("同城用户：userId="+user.getUserId()+"|昵称："+user.getNickName()+"|性别："+user.getSex()
                +"|主播状态="+user.getIsHost()+"|vip="+user.getIsVip()+"|省="+user.getLocationProvince()+"|市="+user.getLocationCity()
                +"|城市编号="+cityId);
        if (cityId == -1) {
            int end = (startNum + pageSize) - 1;

            List<String> userList = new ArrayList<>();
            List<String> keyList = getLocationKey(user, otherSex,0);

            for (String key : keyList) {
                getUserList(key, userList, user.getUserId(), end - userList.size());
                if (userList.size() > end) {
                    break;
                }
            }

            if (userList.size() == 0) {
                return new ArrayList<>();
            } else {
                if (userList.size() <= end) {
                    return userList.subList(startNum, userList.size());
                } else {
                    return userList.subList(startNum, end+1);
                }
            }
        } else {
            int end = (startNum + pageSize) - 1;
            List<String> userList = new ArrayList<>();

            List<String> keyList = getLocationKey(user, otherSex,1);

            for (String key : keyList) {
                getSameCityUserList(key, userList,cityId,user.getUserId(), end - userList.size());
                if (userList.size() > end) {
                    break;
                }
            }


            if(userList.size()<=end){
                List<Integer> cityList = areaDao.selectCityNotInCityId(cityId);
                cityList.add(-1);
                for(int id : cityList){
                    for (String key : keyList) {
                        getSameCityUserList(key, userList,id,user.getUserId(), end - userList.size());
                        if (userList.size() > end) {
                            break;
                        }
                    }
                }
            }
            log.info("startNum="+startNum+"|end="+end);
            if (userList.size() == 0) {
                return new ArrayList<>();
            } else {
                if (userList.size() <= end) {
                    return userList.subList(startNum, userList.size());
                } else {
                    return userList.subList(startNum, end+1);
                }
            }

        }

    }

    /**
     * 根据不同类型获取不同key
     * @param user
     * @param otherSex
     * @param isUseOtherUser  是否使用普通同性用户填充，0，填充，1：不填充
     * @return
     */
    private List<String> getLocationKey(User user, int otherSex,int isUseOtherUser) {
        List<String> keyList = new ArrayList<>();
        if(user.getIsHost()==2){
            keyList.add(USER_LOCATION_HOST_ONLINE_KEY + otherSex);
            keyList.add(USER_LOCATION_HOST_ONLINE_KEY + user.getSex());
            if(isUseOtherUser==0){
                keyList.add(USER_LOCATION_VIP_ONLINE_KEY + user.getSex());
                keyList.add(USER_LOCATION_OTHER_ONLINE_KEY + user.getSex());
            }
        }
        keyList.add(USER_LOCATION_VIP_ONLINE_KEY + otherSex);
        keyList.add(USER_LOCATION_OTHER_ONLINE_KEY + otherSex);

        return keyList;
    }

    /**
     * 获取user集合
     *
     * @param key
     * @param userList
     * @param userId
     * @param size
     */
    private void getUserList(String key, List<String> userList, long userId, int size) {
        Set<String> set = stringRedisTemplate.opsForZSet().reverseRange(key, 0, size);
        if (set != null) {
            set.remove(userId+"");
            if (set.size() > 0) {
                userList.addAll(set);
            }
        }

    }


    private void getSameCityUserList(String key, List<String> userList, int cityId, long userId, int size) {

        Set<String> set = stringRedisTemplate.opsForZSet().reverseRangeByScore(key, cityId, cityId, 0, size);

        if (set != null) {
            set.remove(userId+"");
            if (set.size() > 0) {
                userList.addAll(set);
            }
        }




    }

}
